varying vec3 normal;
varying vec3 light0;
varying vec3 light1;
varying vec3 halfVector0;
varying vec3 halfVector1;
uniform sampler2D textureMap;
uniform sampler2DShadow shadowMap0;
uniform sampler2DShadow shadowMap1;	
float dt = 0.009765625;

vec4 ApplySpotLight()
{
	vec3 n;
	vec3 halfVector; 
	float angleNormalLight;
	float angleNormalHalf;
	vec4 color = gl_LightModel.ambient * gl_FrontMaterial.ambient;
	float att;
	float spotEffect;

	vec4 diffuse1 = gl_FrontMaterial.diffuse * gl_LightSource[1].diffuse;
	vec4 ambient1 = gl_FrontMaterial.ambient * gl_LightSource[1].ambient;

	n = normalize(normal);
	vec3 lightDirection1 = normalize(light1);
	float lightDistance1 = length(light1);

	angleNormalLight = max(dot(n,normalize(lightDirection1)), 0.0);

	if (angleNormalLight > 0.0)
	{
		spotEffect = dot(normalize(gl_LightSource[1].spotDirection), normalize(-lightDirection1));
		if (spotEffect > gl_LightSource[1].spotCosCutoff)
		{
			spotEffect = pow(spotEffect, gl_LightSource[1].spotExponent);
			att = spotEffect / (gl_LightSource[1].constantAttenuation +
				gl_LightSource[1].linearAttenuation * lightDistance1 +
				gl_LightSource[1].quadraticAttenuation * lightDistance1 * lightDistance1);

			color += att * (diffuse1 * angleNormalLight + ambient1);
			halfVector = normalize(halfVector1);
			angleNormalHalf = max(dot(n, halfVector), 0.0);
			color += att * gl_FrontMaterial.specular * gl_LightSource[1].specular * pow(angleNormalHalf, gl_FrontMaterial.shininess);
		}
	}
	return color;
}

vec4 ApplyPointLight()
{
	vec3 n;
	vec3 halfVector;
	vec3 viewVector;
	vec3 lightDirection;
	float angleNormalLight,angleNormalHalf;
	vec4 color = gl_LightModel.ambient * gl_FrontMaterial.ambient;
	float att;

	vec4 diffuse0 = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
	vec4 ambient0 = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
	
	n = normalize(normal);
	vec3 lightDirection0 = normalize(light0);
	float lightDistance0 = length(light0);
	angleNormalLight = max(dot(n,normalize(lightDirection0)),0.0);
	if (angleNormalLight > 0.0)
	{
		att = 1.0 / (gl_LightSource[0].constantAttenuation +
				gl_LightSource[0].linearAttenuation * lightDistance0 +
				gl_LightSource[0].quadraticAttenuation * lightDistance0 * lightDistance0);
		color += att * (diffuse0 * angleNormalLight + ambient0);
		halfVector = normalize(halfVector0);
		angleNormalHalf = max(dot(n,halfVector),0.0);
		color += att * gl_FrontMaterial.specular * gl_LightSource[0].specular * 
							pow(angleNormalHalf, gl_FrontMaterial.shininess);
	}
	return color;
}

float SamplePointShadowPCF()
{
	float shadowSample0 = shadow2DProj(shadowMap0, gl_TexCoord[1]).r;
	float shadowSample1 = shadow2DProj(shadowMap0, gl_TexCoord[1] + vec4(0.0, dt, 0.0, 0.0)).r;
	float shadowSample2 = shadow2DProj(shadowMap0, gl_TexCoord[1] + vec4(dt, dt, 0.0, 0.0)).r;
	float shadowSample3 = shadow2DProj(shadowMap0, gl_TexCoord[1] + vec4(dt, 0.0, 0.0, 0.0)).r;
	float shadowColor = 0.25 * (shadowSample0 + shadowSample1 + shadowSample2 + shadowSample3);
	return shadowColor;
}

float SampleSpotShadowPCF()
{
	float shadowSample0 = shadow2DProj(shadowMap1, gl_TexCoord[2]).r;
	float shadowSample1 = shadow2DProj(shadowMap1, gl_TexCoord[2] + vec4(0.0, dt, 0.0, 0.0)).r;
	float shadowSample2 = shadow2DProj(shadowMap1, gl_TexCoord[2] + vec4(dt, dt, 0.0, 0.0)).r;
	float shadowSample3 = shadow2DProj(shadowMap1, gl_TexCoord[2] + vec4(dt, 0.0, 0.0, 0.0)).r;
	float shadowColor = 0.25 * (shadowSample0 + shadowSample1 + shadowSample2 + shadowSample3);
	return shadowColor;
}

void main(void)
{
	float pointShadowColor = SamplePointShadowPCF();
	float spotShadowColor =SampleSpotShadowPCF();
	vec4 textureColor = texture2D(textureMap, gl_TexCoord[0].st);
	vec4 pointLightColor = ApplyPointLight();
	vec4 spotLightColor = ApplySpotLight();
		
	gl_FragColor = textureColor * ((spotShadowColor * spotLightColor) + (pointShadowColor * pointLightColor)) + 0.1;
}
